home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 14 / CU Amiga Magazine's Super CD-ROM 14 (1997)(EMAP Images)(GB)(Track 1 of 3)[!][issue 1997-09].iso / CUCD / Programming / Mesa-2.2 / src / pixel.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-03-13  |  24.7 KB  |  983 lines

  1. /* $Id: pixel.c,v 1.6 1997/02/09 20:05:03 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  2.2
  6.  * Copyright (C) 1995-1997  Brian Paul
  7.  *
  8.  * This library is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU Library General Public
  10.  * License as published by the Free Software Foundation; either
  11.  * version 2 of the License, or (at your option) any later version.
  12.  *
  13.  * This library is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.  * Library General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU Library General Public
  19.  * License along with this library; if not, write to the Free
  20.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  */
  22.  
  23.  
  24. /*
  25.  * $Log: pixel.c,v $
  26.  * Revision 1.6  1997/02/09 20:05:03  brianp
  27.  * new arguments for gl_pixel_addr_in_image()
  28.  *
  29.  * Revision 1.5  1997/02/09 18:52:37  brianp
  30.  * added GL_EXT_texture3D support
  31.  *
  32.  * Revision 1.4  1996/11/06 04:09:37  brianp
  33.  * added a missing return after a gl_error() call
  34.  *
  35.  * Revision 1.3  1996/09/26 22:35:10  brianp
  36.  * fixed a few compiler warnings from IRIX 6 -n32 and -64 compiler
  37.  *
  38.  * Revision 1.2  1996/09/15 14:18:55  brianp
  39.  * now use GLframebuffer and GLvisual
  40.  *
  41.  * Revision 1.1  1996/09/13 01:38:16  brianp
  42.  * Initial revision
  43.  *
  44.  */
  45.  
  46.  
  47. /*
  48.  * glPixelStore, glPixelTransfer, glPixelMap, glPixelZoom, etc.
  49.  */
  50.  
  51.  
  52.  
  53. #include <assert.h>
  54. #include <stdio.h>
  55. #include <stdlib.h>
  56. #include <string.h>
  57. #include "context.h"
  58. #include "dlist.h"
  59. #include "macros.h"
  60. #include "pixel.h"
  61. #include "image.h"
  62. #include "span.h"
  63. #include "stencil.h"
  64. #include "types.h"
  65.  
  66.  
  67.  
  68. /*
  69.  * Determine if we can use the optimized glDrawPixels function.
  70.  */
  71. static void update_drawpixels_state( GLcontext *ctx )
  72. {
  73.    if (ctx->Visual->RGBAflag==GL_TRUE &&
  74.        ctx->Visual->EightBitColor &&
  75.        ctx->Pixel.RedBias==0.0   && ctx->Pixel.RedScale==1.0 &&
  76.        ctx->Pixel.GreenBias==0.0 && ctx->Pixel.GreenScale==1.0 &&
  77.        ctx->Pixel.BlueBias==0.0  && ctx->Pixel.BlueScale==1.0 &&
  78.        ctx->Pixel.AlphaBias==0.0 && ctx->Pixel.AlphaScale==1.0 &&
  79.        ctx->Pixel.MapColorFlag==GL_FALSE &&
  80.        ctx->Pixel.ZoomX==1.0 && ctx->Pixel.ZoomY==1.0 &&
  81. /*       ctx->Unpack.Alignment==4 &&*/
  82.        ctx->Unpack.RowLength==0 &&
  83.        ctx->Unpack.SkipPixels==0 &&
  84.        ctx->Unpack.SkipRows==0 &&
  85.        ctx->Unpack.SwapBytes==0 &&
  86.        ctx->Unpack.LsbFirst==0) {
  87.       ctx->FastDrawPixels = GL_TRUE;
  88.    }
  89.    else {
  90.       ctx->FastDrawPixels = GL_FALSE;
  91.    }
  92. }
  93.  
  94.  
  95.  
  96.  
  97. /**********************************************************************/
  98. /*****                    glPixelZoom                             *****/
  99. /**********************************************************************/
  100.  
  101.  
  102.  
  103. void gl_PixelZoom( GLcontext *ctx, GLfloat xfactor, GLfloat yfactor )
  104. {
  105.    if (INSIDE_BEGIN_END(ctx)) {
  106.       gl_error( ctx, GL_INVALID_OPERATION, "glPixelZoom" );
  107.       return;
  108.    }
  109.    ctx->Pixel.ZoomX = xfactor;
  110.    ctx->Pixel.ZoomY = yfactor;
  111.    update_drawpixels_state( ctx );
  112. }
  113.  
  114.  
  115.  
  116.  
  117. /*
  118.  * Write a span of pixels to the frame buffer while applying a pixel zoom.
  119.  * This is only used by glDrawPixels and glCopyPixels.
  120.  * Input:  n - number of pixels in input row
  121.  *         x, y - destination of the span
  122.  *         z - depth values for the span
  123.  *         red, green, blue, alpha - array of colors
  124.  *         y0 - location of first row in the image we're drawing.
  125.  */
  126. void
  127. gl_write_zoomed_color_span( GLcontext *ctx,
  128.                             GLuint n, GLint x, GLint y, const GLdepth z[],
  129.                             const GLubyte red[], const GLubyte green[],
  130.                             const GLubyte blue[], const GLubyte alpha[],
  131.                             GLint y0 )
  132. {
  133.    GLint m;
  134.    GLint r0, r1, row, r;
  135.    GLint i, j, skipcol;
  136.    GLubyte zred[MAX_WIDTH], zgreen[MAX_WIDTH];  /* zoomed pixel colors */
  137.    GLubyte zblue[MAX_WIDTH], zalpha[MAX_WIDTH];
  138.    GLdepth zdepth[MAX_WIDTH];  /* zoomed depth values */
  139.    GLint maxwidth = MIN2( ctx->Buffer->Width, MAX_WIDTH );
  140.  
  141.    /* compute width of output row */
  142.    m = (GLint) ABSF( n * ctx->Pixel.ZoomX );
  143.    if (m==0) {
  144.       return;
  145.    }
  146.    if (ctx->Pixel.ZoomX<0.0) {
  147.       /* adjust x coordinate for left/right mirroring */
  148.       x = x - m;
  149.    }
  150.  
  151.    /* compute which rows to draw */
  152.    row = y-y0;
  153.    r0 = y0 + (GLint) (row * ctx->Pixel.ZoomY);
  154.    r1 = y0 + (GLint) ((row+1) * ctx->Pixel.ZoomY);
  155.    if (r0==r1) {
  156.       return;
  157.    }
  158.    else if (r1<r0) {
  159.       GLint rtmp = r1;
  160.       r1 = r0;
  161.       r0 = rtmp;
  162.    }
  163.  
  164.    /* return early if r0...r1 is above or below window */
  165.    if (r0<0 && r1<0) {
  166.       /* below window */
  167.       return;
  168.    }
  169.    if (r0>=ctx->Buffer->Height && r1>=ctx->Buffer->Height) {
  170.       /* above window */
  171.       return;
  172.    }
  173.  
  174.    /* check if left edge is outside window */
  175.    skipcol = 0;
  176.    if (x<0) {
  177.       skipcol = -x;
  178.       m += x;
  179.    }
  180.    /* make sure span isn't too long or short */
  181.    if (m>maxwidth) {
  182.       m = maxwidth;
  183.    }
  184.    else if (m<=0) {
  185.       return;
  186.    }
  187.  
  188.    assert( m <= MAX_WIDTH );
  189.  
  190.    /* zoom the span horizontally */
  191.    if (ctx->Pixel.ZoomX==-1.0F) {
  192.       /* n==m */
  193.       for (j=0;j<m;j++) {
  194.          i = n - (j+skipcol) - 1;
  195.          zred[j]   = red[i];
  196.          zgreen[j] = green[i];
  197.          zblue[j]  = blue[i];
  198.          zalpha[j] = alpha[i];
  199.          zdepth[j] = z[i];
  200.       }
  201.    }
  202.    else {
  203.       GLfloat xscale = 1.0F / ctx->Pixel.ZoomX;
  204.       for (j=0;j<m;j++) {
  205.          i = (j+skipcol) * xscale;
  206.          if (i<0)  i = n + i - 1;
  207.          zred[j]   = red[i];
  208.          zgreen[j] = green[i];
  209.          zblue[j]  = blue[i];
  210.          zalpha[j] = alpha[i];
  211.          zdepth[j] = z[i];
  212.       }
  213.    }
  214.  
  215.    /* write the span */
  216.    for (r=r0; r<r1; r++) {
  217.       gl_write_color_span( ctx, m, x+skipcol, r, zdepth,
  218.                            zred, zgreen, zblue, zalpha, GL_BITMAP );
  219.    }
  220. }
  221.  
  222.  
  223.  
  224. /*
  225.  * As above, but write CI pixels.
  226.  */
  227. void
  228. gl_write_zoomed_index_span( GLcontext *ctx,
  229.                             GLuint n, GLint x, GLint y, const GLdepth z[],
  230.                             const GLuint indexes[], GLint y0 )
  231. {
  232.    GLint m;
  233.    GLint r0, r1, row, r;
  234.    GLint i, j, skipcol;
  235.    GLuint zindexes[MAX_WIDTH];  /* zoomed color indexes */
  236.    GLdepth zdepth[MAX_WIDTH];  /* zoomed depth values */
  237.    GLint maxwidth = MIN2( ctx->Buffer->Width, MAX_WIDTH );
  238.  
  239.    /* compute width of output row */
  240.    m = (GLint) ABSF( n * ctx->Pixel.ZoomX );
  241.    if (m==0) {
  242.       return;
  243.    }
  244.    if (ctx->Pixel.ZoomX<0.0) {
  245.       /* adjust x coordinate for left/right mirroring */
  246.       x = x - m;
  247.    }
  248.  
  249.    /* compute which rows to draw */
  250.    row = y-y0;
  251.    r0 = y0 + (GLint) (row * ctx->Pixel.ZoomY);
  252.    r1 = y0 + (GLint) ((row+1) * ctx->Pixel.ZoomY);
  253.    if (r0==r1) {
  254.       return;
  255.    }
  256.    else if (r1<r0) {
  257.       GLint rtmp = r1;
  258.       r1 = r0;
  259.       r0 = rtmp;
  260.    }
  261.  
  262.    /* return early if r0...r1 is above or below window */
  263.    if (r0<0 && r1<0) {
  264.       /* below window */
  265.       return;
  266.    }
  267.    if (r0>=ctx->Buffer->Height && r1>=ctx->Buffer->Height) {
  268.       /* above window */
  269.       return;
  270.    }
  271.  
  272.    /* check if left edge is outside window */
  273.    skipcol = 0;
  274.    if (x<0) {
  275.       skipcol = -x;
  276.       m += x;
  277.    }
  278.    /* make sure span isn't too long or short */
  279.    if (m>maxwidth) {
  280.       m = maxwidth;
  281.    }
  282.    else if (m<=0) {
  283.       return;
  284.    }
  285.  
  286.    assert( m <= MAX_WIDTH );
  287.  
  288.    /* zoom the span horizontally */
  289.    if (ctx->Pixel.ZoomX==-1.0F) {
  290.       /* n==m */
  291.       for (j=0;j<m;j++) {
  292.          i = n - (j+skipcol) - 1;
  293.          zindexes[j] = indexes[i];
  294.          zdepth[j]   = z[i];
  295.       }
  296.    }
  297.    else {
  298.       GLfloat xscale = 1.0F / ctx->Pixel.ZoomX;
  299.       for (j=0;j<m;j++) {
  300.          i = (j+skipcol) * xscale;
  301.          if (i<0)  i = n + i - 1;
  302.          zindexes[j] = indexes[i];
  303.          zdepth[j] = z[i];
  304.       }
  305.    }
  306.  
  307.    /* write the span */
  308.    for (r=r0; r<r1; r++) {
  309.       gl_write_index_span( ctx, m, x+skipcol, r, zdepth, zindexes, GL_BITMAP );
  310.    }
  311. }
  312.  
  313.  
  314.  
  315. /*
  316.  * As above, but write stencil values.
  317.  */
  318. void
  319. gl_write_zoomed_stencil_span( GLcontext *ctx,
  320.                               GLuint n, GLint x, GLint y,
  321.                               const GLubyte stencil[], GLint y0 )
  322. {
  323.    GLint m;
  324.    GLint r0, r1, row, r;
  325.    GLint i, j, skipcol;
  326.    GLubyte zstencil[MAX_WIDTH];  /* zoomed stencil values */
  327.    GLint maxwidth = MIN2( ctx->Buffer->Width, MAX_WIDTH );
  328.  
  329.    /* compute width of output row */
  330.    m = (GLint) ABSF( n * ctx->Pixel.ZoomX );
  331.    if (m==0) {
  332.       return;
  333.    }
  334.    if (ctx->Pixel.ZoomX<0.0) {
  335.       /* adjust x coordinate for left/right mirroring */
  336.       x = x - m;
  337.    }
  338.  
  339.    /* compute which rows to draw */
  340.    row = y-y0;
  341.    r0 = y0 + (GLint) (row * ctx->Pixel.ZoomY);
  342.    r1 = y0 + (GLint) ((row+1) * ctx->Pixel.ZoomY);
  343.    if (r0==r1) {
  344.       return;
  345.    }
  346.    else if (r1<r0) {
  347.       GLint rtmp = r1;
  348.       r1 = r0;
  349.       r0 = rtmp;
  350.    }
  351.  
  352.    /* return early if r0...r1 is above or below window */
  353.    if (r0<0 && r1<0) {
  354.       /* below window */
  355.       return;
  356.    }
  357.    if (r0>=ctx->Buffer->Height && r1>=ctx->Buffer->Height) {
  358.       /* above window */
  359.       return;
  360.    }
  361.  
  362.    /* check if left edge is outside window */
  363.    skipcol = 0;
  364.    if (x<0) {
  365.       skipcol = -x;
  366.       m += x;
  367.    }
  368.    /* make sure span isn't too long or short */
  369.    if (m>maxwidth) {
  370.       m = maxwidth;
  371.    }
  372.    else if (m<=0) {
  373.       return;
  374.    }
  375.  
  376.    assert( m <= MAX_WIDTH );
  377.  
  378.    /* zoom the span horizontally */
  379.    if (ctx->Pixel.ZoomX==-1.0F) {
  380.       /* n==m */
  381.       for (j=0;j<m;j++) {
  382.          i = n - (j+skipcol) - 1;
  383.          zstencil[j] = stencil[i];
  384.       }
  385.    }
  386.    else {
  387.       GLfloat xscale = 1.0F / ctx->Pixel.ZoomX;
  388.       for (j=0;j<m;j++) {
  389.          i = (j+skipcol) * xscale;
  390.          if (i<0)  i = n + i - 1;
  391.          zstencil[j] = stencil[i];
  392.       }
  393.    }
  394.  
  395.    /* write the span */
  396.    for (r=r0; r<r1; r++) {
  397.       gl_write_stencil_span( ctx, m, x+skipcol, r, zstencil );
  398.    }
  399. }
  400.  
  401.  
  402.  
  403.  
  404. /**********************************************************************/
  405. /*****                    glPixelStore                            *****/
  406. /**********************************************************************/
  407.  
  408.  
  409. void gl_PixelStorei( GLcontext *ctx, GLenum pname, GLint param )
  410. {
  411.    /* NOTE: this call can't be compiled into the display list */
  412.  
  413.    if (INSIDE_BEGIN_END(ctx)) {
  414.       gl_error( ctx, GL_INVALID_OPERATION, "glPixelStore" );
  415.       return;
  416.    }
  417.  
  418.    switch (pname) {
  419.       case GL_PACK_SWAP_BYTES:
  420.          ctx->Pack.SwapBytes = param ? GL_TRUE : GL_FALSE;
  421.      break;
  422.       case GL_PACK_LSB_FIRST:
  423.          ctx->Pack.LsbFirst = param ? GL_TRUE : GL_FALSE;
  424.      break;
  425.       case GL_PACK_ROW_LENGTH:
  426.      if (param<0) {
  427.         gl_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
  428.      }
  429.      else {
  430.         ctx->Pack.RowLength = param;
  431.      }
  432.      break;
  433.       case GL_PACK_SKIP_PIXELS:
  434.      if (param<0) {
  435.         gl_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
  436.      }
  437.      else {
  438.         ctx->Pack.SkipPixels = param;
  439.      }
  440.      break;
  441.       case GL_PACK_SKIP_ROWS:
  442.      if (param<0) {
  443.         gl_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
  444.      }
  445.      else {
  446.         ctx->Pack.SkipRows = param;
  447.      }
  448.      break;
  449.       case GL_PACK_ALIGNMENT:
  450.          if (param==1 || param==2 || param==4 || param==8) {
  451.         ctx->Pack.Alignment = param;
  452.      }
  453.      else {
  454.         gl_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
  455.      }
  456.      break;
  457.       case GL_UNPACK_SWAP_BYTES:
  458.      ctx->Unpack.SwapBytes = param ? GL_TRUE : GL_FALSE;
  459.          break;
  460.       case GL_UNPACK_LSB_FIRST:
  461.      ctx->Unpack.LsbFirst = param ? GL_TRUE : GL_FALSE;
  462.      break;
  463.       case GL_UNPACK_ROW_LENGTH:
  464.      if (param<0) {
  465.         gl_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
  466.      }
  467.      else {
  468.         ctx->Unpack.RowLength = param;
  469.      }
  470.      break;
  471.       case GL_UNPACK_SKIP_PIXELS:
  472.      if (param<0) {
  473.         gl_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
  474.      }
  475.      else {
  476.         ctx->Unpack.SkipPixels = param;
  477.      }
  478.      break;
  479.       case GL_UNPACK_SKIP_ROWS:
  480.      if (param<0) {
  481.         gl_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" );
  482.      }
  483.      else {
  484.         ctx->Unpack.SkipRows = param;
  485.      }
  486.      break;
  487.       case GL_UNPACK_ALIGNMENT:
  488.          if (param==1 || param==2 || param==4 || param==8) {
  489.         ctx->Unpack.Alignment = param;
  490.      }
  491.      else {
  492.         gl_error( ctx, GL_INVALID_VALUE, "glPixelStore" );
  493.      }
  494.      break;
  495.       default:
  496.      gl_error( ctx, GL_INVALID_ENUM, "glPixelStore" );
  497.    }
  498.    update_drawpixels_state( ctx );
  499. }
  500.  
  501.  
  502.  
  503.  
  504.  
  505. /**********************************************************************/
  506. /*****                         glPixelMap                         *****/
  507. /**********************************************************************/
  508.  
  509.  
  510.  
  511. void gl_PixelMapfv( GLcontext *ctx,
  512.                     GLenum map, GLint mapsize, const GLfloat *values )
  513. {
  514.    GLuint i;
  515.  
  516.    if (INSIDE_BEGIN_END(ctx)) {
  517.       gl_error( ctx, GL_INVALID_OPERATION, "glPixelMapfv" );
  518.       return;
  519.    }
  520.  
  521.    if (mapsize<0 || mapsize>MAX_PIXEL_MAP_TABLE) {
  522.       gl_error( ctx, GL_INVALID_VALUE, "glPixelMapfv(mapsize)" );
  523.       return;
  524.    }
  525.  
  526.    if (map>=GL_PIXEL_MAP_S_TO_S && map<=GL_PIXEL_MAP_I_TO_A) {
  527.       /* test that mapsize is a power of two */
  528.       GLuint p;
  529.       GLboolean ok = GL_FALSE;
  530.       for (p=1; p<=MAX_PIXEL_MAP_TABLE; p=p<<1) {
  531.      if ( (p&mapsize) == p ) {
  532.         ok = GL_TRUE;
  533.         break;
  534.      }
  535.       }
  536.       if (!ok) {
  537.      gl_error( ctx, GL_INVALID_VALUE, "glPixelMapfv(mapsize)" );
  538.          return;
  539.       }
  540.    }
  541.  
  542.    switch (map) {
  543.       case GL_PIXEL_MAP_S_TO_S:
  544.          ctx->Pixel.MapStoSsize = mapsize;
  545.          for (i=0;i<mapsize;i++) {
  546.         ctx->Pixel.MapStoS[i] = (GLint) values[i];
  547.      }
  548.      break;
  549.       case GL_PIXEL_MAP_I_TO_I:
  550.          ctx->Pixel.MapItoIsize = mapsize;
  551.          for (i=0;i<mapsize;i++) {
  552.         ctx->Pixel.MapItoI[i] = (GLint) values[i];
  553.      }
  554.      break;
  555.       case GL_PIXEL_MAP_I_TO_R:
  556.          ctx->Pixel.MapItoRsize = mapsize;
  557.          for (i=0;i<mapsize;i++) {
  558.         ctx->Pixel.MapItoR[i] = CLAMP( values[i], 0.0, 1.0 );
  559.      }
  560.      break;
  561.       case GL_PIXEL_MAP_I_TO_G:
  562.          ctx->Pixel.MapItoGsize = mapsize;
  563.          for (i=0;i<mapsize;i++) {
  564.         ctx->Pixel.MapItoG[i] = CLAMP( values[i], 0.0, 1.0 );
  565.      }
  566.      break;
  567.       case GL_PIXEL_MAP_I_TO_B:
  568.          ctx->Pixel.MapItoBsize = mapsize;
  569.          for (i=0;i<mapsize;i++) {
  570.         ctx->Pixel.MapItoB[i] = CLAMP( values[i], 0.0, 1.0 );
  571.      }
  572.      break;
  573.       case GL_PIXEL_MAP_I_TO_A:
  574.          ctx->Pixel.MapItoAsize = mapsize;
  575.          for (i=0;i<mapsize;i++) {
  576.         ctx->Pixel.MapItoA[i] = CLAMP( values[i], 0.0, 1.0 );
  577.      }
  578.      break;
  579.       case GL_PIXEL_MAP_R_TO_R:
  580.          ctx->Pixel.MapRtoRsize = mapsize;
  581.          for (i=0;i<mapsize;i++) {
  582.         ctx->Pixel.MapRtoR[i] = CLAMP( values[i], 0.0, 1.0 );
  583.      }
  584.      break;
  585.       case GL_PIXEL_MAP_G_TO_G:
  586.          ctx->Pixel.MapGtoGsize = mapsize;
  587.          for (i=0;i<mapsize;i++) {
  588.         ctx->Pixel.MapGtoG[i] = CLAMP( values[i], 0.0, 1.0 );
  589.      }
  590.      break;
  591.       case GL_PIXEL_MAP_B_TO_B:
  592.          ctx->Pixel.MapBtoBsize = mapsize;
  593.          for (i=0;i<mapsize;i++) {
  594.         ctx->Pixel.MapBtoB[i] = CLAMP( values[i], 0.0, 1.0 );
  595.      }
  596.      break;
  597.       case GL_PIXEL_MAP_A_TO_A:
  598.          ctx->Pixel.MapAtoAsize = mapsize;
  599.          for (i=0;i<mapsize;i++) {
  600.         ctx->Pixel.MapAtoA[i] = CLAMP( values[i], 0.0, 1.0 );
  601.      }
  602.      break;
  603.       default:
  604.          gl_error( ctx, GL_INVALID_ENUM, "glPixelMapfv(map)" );
  605.    }
  606. }
  607.  
  608.  
  609.  
  610.  
  611.  
  612. void gl_GetPixelMapfv( GLcontext *ctx, GLenum map, GLfloat *values )
  613. {
  614.    GLuint i;
  615.  
  616.    if (INSIDE_BEGIN_END(ctx)) {
  617.       gl_error( ctx, GL_INVALID_OPERATION, "glGetPixelMapfv" );
  618.       return;
  619.    }
  620.    switch (map) {
  621.       case GL_PIXEL_MAP_I_TO_I:
  622.          for (i=0;i<ctx->Pixel.MapItoIsize;i++) {
  623.         values[i] = (GLfloat) ctx->Pixel.MapItoI[i];
  624.      }
  625.      break;
  626.       case GL_PIXEL_MAP_S_TO_S:
  627.          for (i=0;i<ctx->Pixel.MapStoSsize;i++) {
  628.         values[i] = (GLfloat) ctx->Pixel.MapStoS[i];
  629.      }
  630.      break;
  631.       case GL_PIXEL_MAP_I_TO_R:
  632.          MEMCPY(values,ctx->Pixel.MapItoR,ctx->Pixel.MapItoRsize*sizeof(GLfloat));
  633.      break;
  634.       case GL_PIXEL_MAP_I_TO_G:
  635.          MEMCPY(values,ctx->Pixel.MapItoG,ctx->Pixel.MapItoGsize*sizeof(GLfloat));
  636.      break;
  637.       case GL_PIXEL_MAP_I_TO_B:
  638.          MEMCPY(values,ctx->Pixel.MapItoB,ctx->Pixel.MapItoBsize*sizeof(GLfloat));
  639.      break;
  640.       case GL_PIXEL_MAP_I_TO_A:
  641.          MEMCPY(values,ctx->Pixel.MapItoA,ctx->Pixel.MapItoAsize*sizeof(GLfloat));
  642.      break;
  643.       case GL_PIXEL_MAP_R_TO_R:
  644.          MEMCPY(values,ctx->Pixel.MapRtoR,ctx->Pixel.MapRtoRsize*sizeof(GLfloat));
  645.      break;
  646.       case GL_PIXEL_MAP_G_TO_G:
  647.          MEMCPY(values,ctx->Pixel.MapGtoG,ctx->Pixel.MapGtoGsize*sizeof(GLfloat));
  648.      break;
  649.       case GL_PIXEL_MAP_B_TO_B:
  650.          MEMCPY(values,ctx->Pixel.MapBtoB,ctx->Pixel.MapBtoBsize*sizeof(GLfloat));
  651.      break;
  652.       case GL_PIXEL_MAP_A_TO_A:
  653.          MEMCPY(values,ctx->Pixel.MapAtoA,ctx->Pixel.MapAtoAsize*sizeof(GLfloat));
  654.      break;
  655.       default:
  656.          gl_error( ctx, GL_INVALID_ENUM, "glGetPixelMapfv" );
  657.    }
  658. }
  659.  
  660.  
  661. void gl_GetPixelMapuiv( GLcontext *ctx, GLenum map, GLuint *values )
  662. {
  663.    GLuint i;
  664.  
  665.    if (INSIDE_BEGIN_END(ctx)) {
  666.       gl_error( ctx, GL_INVALID_OPERATION, "glGetPixelMapfv" );
  667.       return;
  668.    }
  669.    switch (map) {
  670.       case GL_PIXEL_MAP_I_TO_I:
  671.          MEMCPY(values, ctx->Pixel.MapItoI, ctx->Pixel.MapItoIsize*sizeof(GLint));
  672.      break;
  673.       case GL_PIXEL_MAP_S_TO_S:
  674.          MEMCPY(values, ctx->Pixel.MapStoS, ctx->Pixel.MapStoSsize*sizeof(GLint));
  675.      break;
  676.       case GL_PIXEL_MAP_I_TO_R:
  677.      for (i=0;i<ctx->Pixel.MapItoRsize;i++) {
  678.         values[i] = FLOAT_TO_UINT( ctx->Pixel.MapItoR[i] );
  679.      }
  680.      break;
  681.       case GL_PIXEL_MAP_I_TO_G:
  682.      for (i=0;i<ctx->Pixel.MapItoGsize;i++) {
  683.         values[i] = FLOAT_TO_UINT( ctx->Pixel.MapItoG[i] );
  684.      }
  685.      break;
  686.       case GL_PIXEL_MAP_I_TO_B:
  687.      for (i=0;i<ctx->Pixel.MapItoBsize;i++) {
  688.         values[i] = FLOAT_TO_UINT( ctx->Pixel.MapItoB[i] );
  689.      }
  690.      break;
  691.       case GL_PIXEL_MAP_I_TO_A:
  692.      for (i=0;i<ctx->Pixel.MapItoAsize;i++) {
  693.         values[i] = FLOAT_TO_UINT( ctx->Pixel.MapItoA[i] );
  694.      }
  695.      break;
  696.       case GL_PIXEL_MAP_R_TO_R:
  697.      for (i=0;i<ctx->Pixel.MapRtoRsize;i++) {
  698.         values[i] = FLOAT_TO_UINT( ctx->Pixel.MapRtoR[i] );
  699.      }
  700.      break;
  701.       case GL_PIXEL_MAP_G_TO_G:
  702.      for (i=0;i<ctx->Pixel.MapGtoGsize;i++) {
  703.         values[i] = FLOAT_TO_UINT( ctx->Pixel.MapGtoG[i] );
  704.      }
  705.      break;
  706.       case GL_PIXEL_MAP_B_TO_B:
  707.      for (i=0;i<ctx->Pixel.MapBtoBsize;i++) {
  708.         values[i] = FLOAT_TO_UINT( ctx->Pixel.MapBtoB[i] );
  709.      }
  710.      break;
  711.       case GL_PIXEL_MAP_A_TO_A:
  712.      for (i=0;i<ctx->Pixel.MapAtoAsize;i++) {
  713.         values[i] = FLOAT_TO_UINT( ctx->Pixel.MapAtoA[i] );
  714.      }
  715.      break;
  716.       default:
  717.          gl_error( ctx, GL_INVALID_ENUM, "glGetPixelMapfv" );
  718.    }
  719. }
  720.  
  721.  
  722. void gl_GetPixelMapusv( GLcontext *ctx, GLenum map, GLushort *values )
  723. {
  724.    GLuint i;
  725.  
  726.    if (INSIDE_BEGIN_END(ctx)) {
  727.       gl_error( ctx, GL_INVALID_OPERATION, "glGetPixelMapfv" );
  728.       return;
  729.    }
  730.    switch (map) {
  731.       case GL_PIXEL_MAP_I_TO_I:
  732.      for (i=0;i<ctx->Pixel.MapItoIsize;i++) {
  733.         values[i] = (GLushort) ctx->Pixel.MapItoI[i];
  734.      }
  735.      break;
  736.       case GL_PIXEL_MAP_S_TO_S:
  737.      for (i=0;i<ctx->Pixel.MapStoSsize;i++) {
  738.         values[i] = (GLushort) ctx->Pixel.MapStoS[i];
  739.      }
  740.      break;
  741.       case GL_PIXEL_MAP_I_TO_R:
  742.      for (i=0;i<ctx->Pixel.MapItoRsize;i++) {
  743.         values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapItoR[i] );
  744.      }
  745.      break;
  746.       case GL_PIXEL_MAP_I_TO_G:
  747.      for (i=0;i<ctx->Pixel.MapItoGsize;i++) {
  748.         values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapItoG[i] );
  749.      }
  750.      break;
  751.       case GL_PIXEL_MAP_I_TO_B:
  752.      for (i=0;i<ctx->Pixel.MapItoBsize;i++) {
  753.         values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapItoB[i] );
  754.      }
  755.      break;
  756.       case GL_PIXEL_MAP_I_TO_A:
  757.      for (i=0;i<ctx->Pixel.MapItoAsize;i++) {
  758.         values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapItoA[i] );
  759.      }
  760.      break;
  761.       case GL_PIXEL_MAP_R_TO_R:
  762.      for (i=0;i<ctx->Pixel.MapRtoRsize;i++) {
  763.         values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapRtoR[i] );
  764.      }
  765.      break;
  766.       case GL_PIXEL_MAP_G_TO_G:
  767.      for (i=0;i<ctx->Pixel.MapGtoGsize;i++) {
  768.         values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapGtoG[i] );
  769.      }
  770.      break;
  771.       case GL_PIXEL_MAP_B_TO_B:
  772.      for (i=0;i<ctx->Pixel.MapBtoBsize;i++) {
  773.         values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapBtoB[i] );
  774.      }
  775.      break;
  776.       case GL_PIXEL_MAP_A_TO_A:
  777.      for (i=0;i<ctx->Pixel.MapAtoAsize;i++) {
  778.         values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapAtoA[i] );
  779.      }
  780.      break;
  781.       default:
  782.          gl_error( ctx, GL_INVALID_ENUM, "glGetPixelMapfv" );
  783.    }
  784. }
  785.  
  786.  
  787.  
  788. /**********************************************************************/
  789. /*****                       glPixelTransfer                      *****/
  790. /**********************************************************************/
  791.  
  792.  
  793. /*
  794.  * Implements glPixelTransfer[fi] whether called immediately or from a
  795.  * display list.
  796.  */
  797. void gl_PixelTransferf( GLcontext *ctx, GLenum pname, GLfloat param )
  798. {
  799.    if (INSIDE_BEGIN_END(ctx)) {
  800.       gl_error( ctx, GL_INVALID_OPERATION, "glPixelTransfer" );
  801.       return;
  802.    }
  803.  
  804.    switch (pname) {
  805.       case GL_MAP_COLOR:
  806.          ctx->Pixel.MapColorFlag = param ? GL_TRUE : GL_FALSE;
  807.      break;
  808.       case GL_MAP_STENCIL:
  809.          ctx->Pixel.MapStencilFlag = param ? GL_TRUE : GL_FALSE;
  810.      break;
  811.       case GL_INDEX_SHIFT:
  812.          ctx->Pixel.IndexShift = (GLint) param;
  813.      break;
  814.       case GL_INDEX_OFFSET:
  815.          ctx->Pixel.IndexOffset = (GLint) param;
  816.      break;
  817.       case GL_RED_SCALE:
  818.          ctx->Pixel.RedScale = param;
  819.      break;
  820.       case GL_RED_BIAS:
  821.          ctx->Pixel.RedBias = param;
  822.      break;
  823.       case GL_GREEN_SCALE:
  824.          ctx->Pixel.GreenScale = param;
  825.      break;
  826.       case GL_GREEN_BIAS:
  827.          ctx->Pixel.GreenBias = param;
  828.      break;
  829.       case GL_BLUE_SCALE:
  830.          ctx->Pixel.BlueScale = param;
  831.      break;
  832.       case GL_BLUE_BIAS:
  833.          ctx->Pixel.BlueBias = param;
  834.      break;
  835.       case GL_ALPHA_SCALE:
  836.          ctx->Pixel.AlphaScale = param;
  837.      break;
  838.       case GL_ALPHA_BIAS:
  839.          ctx->Pixel.AlphaBias = param;
  840.      break;
  841.       case GL_DEPTH_SCALE:
  842.          ctx->Pixel.DepthScale = param;
  843.      break;
  844.       case GL_DEPTH_BIAS:
  845.          ctx->Pixel.DepthBias = param;
  846.      break;
  847.       default:
  848.          gl_error( ctx, GL_INVALID_ENUM, "glPixelTransfer(pname)" );
  849.          return;
  850.    }
  851.    update_drawpixels_state( ctx );
  852. }
  853.  
  854.  
  855.  
  856.  
  857.  
  858. /**********************************************************************/
  859. /*****                 Pixel packing/unpacking                    *****/
  860. /**********************************************************************/
  861.  
  862.  
  863.  
  864. /*
  865.  * Unpack a 2-D pixel array/image.  The unpacked format will be con-
  866.  * tiguous (no "empty" bytes) with byte/bit swapping applied as needed.
  867.  * Input:  same as glDrawPixels
  868.  * Output:  pointer to block of pixel data in same format and type as input
  869.  *          or NULL if error.
  870.  */
  871. GLvoid *gl_unpack_pixels( GLcontext *ctx,
  872.                           GLsizei width, GLsizei height,\
  873.                           GLenum format, GLenum type,
  874.                           const GLvoid *pixels )
  875. {
  876.    GLint s, n;
  877.  
  878.    s = gl_sizeof_type( type );
  879.    if (s<0) {
  880.       gl_error( ctx, GL_INVALID_ENUM, "internal error in gl_unpack(type)" );
  881.       return NULL;
  882.    }
  883.  
  884.    n = gl_components_in_format( format );
  885.    if (n<0) {
  886.       gl_error( ctx, GL_INVALID_ENUM, "gl_unpack_pixels(format)" );
  887.       return NULL;
  888.    }
  889.  
  890.    if (type==GL_BITMAP) {
  891.       /* BITMAP data */
  892.       GLint bytes, i, width_in_bytes;
  893.       GLubyte *buffer, *dst;
  894.       GLvoid *src;
  895.  
  896.       /* Alloc dest storage */
  897.       bytes = CEILING( width * height , 8 );
  898.       buffer = (GLubyte *) malloc( bytes );
  899.       if (!buffer) {
  900.      return NULL;
  901.       }
  902.  
  903.       /* Copy/unpack pixel data to buffer */
  904.       width_in_bytes = CEILING( width, 8 );
  905.       dst = buffer;
  906.       for (i=0;i<height;i++) {
  907.          src = gl_pixel_addr_in_image( &ctx->Unpack, pixels, width, height,
  908.                                        format, type, 0, i, 0 );
  909.          if (!src) {
  910.             free(buffer);
  911.             return NULL;
  912.          }
  913.      MEMCPY( dst, src, width_in_bytes );
  914.      dst += width_in_bytes;
  915.       }
  916.  
  917.       /* Bit flipping */
  918.       if (ctx->Unpack.LsbFirst) {
  919.      gl_flip_bytes( buffer, bytes );
  920.       }
  921.       return (GLvoid *) buffer;
  922.    }
  923.    else {
  924.       /* Non-BITMAP data */
  925.       GLint width_in_bytes, bytes, i;
  926.       GLubyte *buffer, *dst;
  927.       GLvoid *src;
  928.  
  929.       width_in_bytes = width * n * s;
  930.  
  931.       /* Alloc dest storage */
  932.       bytes = height * width_in_bytes;
  933.       buffer = (GLubyte *) malloc( bytes );
  934.       if (!buffer) {
  935.      return NULL;
  936.       }
  937.  
  938.       /* Copy/unpack pixel data to buffer */
  939.       dst = buffer;
  940.       for (i=0;i<height;i++) {
  941.          src = gl_pixel_addr_in_image( &ctx->Unpack, pixels, width, height,
  942.                                        format, type, 0, i, 0 );
  943.          if (!src) {
  944.             free(buffer);
  945.             return NULL;
  946.          }
  947.      MEMCPY( dst, src, width_in_bytes );
  948.      dst += width_in_bytes;
  949.       }
  950.  
  951.       /* Byte swapping */
  952.       if (ctx->Unpack.SwapBytes && s>1) {
  953.      if (s==2) {
  954.         gl_swap2( (GLushort *) buffer, bytes/2 );
  955.      }
  956.      else if (s==4) {
  957.         gl_swap4( (GLuint *) buffer, bytes/4 );
  958.      }
  959.       }
  960.       return (GLvoid *) buffer;
  961.    }
  962. }
  963.  
  964.  
  965.  
  966.  
  967. /*
  968.    if (s>=a) {
  969.       k = n * l;
  970.    }
  971.    else {  *s<a*
  972.       k = (a/s) * ceil( s*n*l / a );
  973.    }
  974.  
  975.    s = size in bytes of a single component
  976.    a = alignment
  977.    n = number of components in a pixel
  978.    l = number of pixels in a row
  979.  
  980.    k = number of components or indices between first pixel in each row in mem.
  981. */
  982.  
  983.